package org.javahispano.javacup.tacticas_aceptadas.silviacambra;

import java.awt.Color;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Vector;

import org.javahispano.javacup.modelo.Comando;
import org.javahispano.javacup.modelo.ComandoGolpearBalon;
import org.javahispano.javacup.modelo.ComandoIrA;
import org.javahispano.javacup.modelo.Constantes;
import org.javahispano.javacup.modelo.EstiloUniforme;
import org.javahispano.javacup.modelo.JugadorDetalle;
import org.javahispano.javacup.modelo.Posicion;
import org.javahispano.javacup.modelo.SituacionPartido;
import org.javahispano.javacup.modelo.Tactica;
import org.javahispano.javacup.modelo.TacticaDetalle;

public class EstamosMuLocos implements Tactica 
{
      double y_portero = -52;
      double y_liberos = y_portero + 1;
      double y_defensas = -36;
      double y_medioCentro = -24;
      double y_medios = -12;
      double y_delanteros = 50;
      double x_centro = 0;
      double x_liberos = 2.25;
      double x_defensas = 12;
      double x_medios = 18;
      double x_delanteros = 2;
      
    Posicion alineacion[] = new Posicion[]
    {
        new Posicion(0.0,-52.0),  // 0
        new Posicion(2.5,-51.0),// 1
        new Posicion(-2.5,-51.0),// 2
        new Posicion(12.0,-36.0),// 3
        new Posicion(-12.0,-36.0),// 4
        new Posicion(0.0,-24.0),// 5
        new Posicion(-18.0,-12.0),// 6
        new Posicion(18.0,-12.0),// 7
        new Posicion(-2.0,50.0),// 8
        new Posicion(2.0,50.0),// 9
        new Posicion(0.0, 50.0)// 10
    };



       class JugadorImpl implements JugadorDetalle {

            String nombre;
            int numero;
            Color piel, pelo;
            double velocidad, remate, presicion;
            boolean portero;
            Posicion posicion;

            public JugadorImpl(String nombre, int numero, Color piel, Color pelo,
                    double velocidad, double remate, double presicion, boolean portero) {
                this.nombre=nombre;
                this.numero=numero;
                this.piel=piel;
                this.pelo=pelo;
                this.velocidad=velocidad;
                this.remate=remate;
                this.presicion=presicion;
                this.portero=portero;
            }

            public String getNombre() {
                return nombre;
            }

            public Color getColorPiel() {
                return piel;
            }

            public Color getColorPelo() {
                return pelo;
            }

            public int getNumero() {
                return numero;
            }

            public boolean esPortero() {
                return portero;
            }

            public double getVelocidad() {
                return velocidad;
            }

            public double getRemate() {
                return remate;
            }

            public double getPresicion() {
                return presicion;
            }

        }
  public TacticaDetalle getDetalle()
  {
    TacticaDetalle detalle = new TacticaDetalle()
    {
      private Color COLOR_1 = new Color(20, 255, 20);
      private Color COLOR_2 = new Color(255, 20, 20);
      
      public String getNombre()
      {
        return "EstamosMuLocos";
      }
      public String getEntrenador()
      {
        return "Silvia Cambra";
      }
      public String getPais()
      {
        return "Spain";
      }
      public Color getColorCamiseta() {
          return COLOR_1;
      }
      public Color getColorPantalon() {
          return COLOR_1;
      }

      public Color getColorFranja() {
          return COLOR_2;
      }

      public Color getColorCalcetas() {
          return COLOR_2;
      }

      public Color getColorPortero() {
          return COLOR_2.darker();
      }

      public EstiloUniforme getEstilo() {
          return EstiloUniforme.FRANJA_DIAGONAL;
      }

      public Color getColorCamiseta2() {
          return COLOR_2;
      }

      public Color getColorPantalon2() {
          return COLOR_2;
      }

      public Color getColorFranja2() {
          return COLOR_1;
      }

      public Color getColorCalcetas2() {
          return COLOR_1;
      }

      public Color getColorPortero2() {
          return COLOR_1.darker();
      }

      public EstiloUniforme getEstilo2() {
          return EstiloUniforme.FRANJA_DIAGONAL;
      }
      
      public JugadorDetalle[] getJugadores()
      {
          JugadorDetalle[] jugadores = new JugadorImpl[11];
          jugadores[0] = new JugadorImpl("PORTERO",      1, new Color(255, 200, 150), new Color(255, 255, 0), 1.0d,  1.0d,  0.5d,  true);
          jugadores[1] = new JugadorImpl("DEFENSA_DCHO", 2, new Color(255, 200, 150), new Color(255, 255, 0), 1.0d,  0.75d, 0.75d, false);
          jugadores[2] = new JugadorImpl("DEFENSA_IZDO", 3, new Color(255, 200, 150), new Color(50, 0, 0),    1.0d, 0.5d,  0.5d, false);
          jugadores[3] = new JugadorImpl("LATERAL_DCHO", 4, new Color(255, 200, 150), new Color(50, 0, 0),    1.0d, 0.5d,  0.5d, false);
          jugadores[4] = new JugadorImpl("LATERAL_IZDO", 5, new Color(255, 200, 150), new Color(50, 0, 0),    1.0d, 0.75d, 0.5d, false);
          jugadores[5] = new JugadorImpl("MEDIO_CENTRO", 6, new Color(255, 200, 150), new Color(255, 255, 0), 1.0d,  1.0d,  0.5d,  false);
          jugadores[6] = new JugadorImpl("MEDIO_IZDO",   7, new Color(255, 200, 150), new Color(255, 255, 0), 1.0d,  1.0d, 0.75d,  false);
          jugadores[7] = new JugadorImpl("MEDIO_DCHO",   8, new Color(255, 200, 150), new Color(255, 255, 0), 1.0d,  1.0d, 0.75d,  false);
          jugadores[8] = new JugadorImpl("PUNTA_DCHO",   9, new Color(190, 150, 100), new Color(255, 255, 0), 1.0d,  1.0d,  0.75d, false);
          jugadores[9] = new JugadorImpl("PUNTA_IZDO",  10, new Color(190, 150, 100), new Color(255, 255, 0), 1.0d,  1.0d,  1.0d,  false);
          jugadores[10]= new JugadorImpl("DELANTERO",   11, new Color(190, 150, 100), new Color(50, 0, 0),    1.0d, 1.0d,  0.5d, false);
          return jugadores;
      }
    };
    // TODO Auto-generated method stub
    return detalle;
  }

    public Posicion[] getPosicionInicial(SituacionPartido sp)
    {
      Posicion[] pos = new Posicion[11];
      pos[0] = new Posicion(x_centro, y_portero);
      pos[1] = new Posicion(x_liberos, y_liberos);
      pos[2] = new Posicion(- x_liberos, y_liberos);
      pos[3] = new Posicion(x_defensas, y_defensas);
      pos[4] = new Posicion(- x_defensas, y_defensas);
      pos[5] = new Posicion(x_centro, y_medioCentro);
      pos[6] = new Posicion(x_medios, y_medios);
      pos[7] = new Posicion(- x_medios, y_medios);
      pos[8] = new Posicion(- x_delanteros, y_delanteros);
      pos[9] = new Posicion(x_delanteros, y_delanteros);
      pos[10] = new Posicion(x_centro, y_delanteros);

      return pos;
    }
  
  
    public Posicion[] getPosicionSaca(SituacionPartido sp) 
    {
      Posicion[] pos = getPosicionInicial(sp);
      for (int i = 0; i < pos.length; i++)
      {
        // Ajustar los jugadores en campo propio
        if (pos[i].getY() > 0)
        {
          pos[i] = new Posicion( pos[i].getX(), 0 );
        }
      }
      pos[10] = new Posicion( Constantes.centroCampoJuego );
      return pos;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) 
    {
      Posicion[] pos = getPosicionInicial(sp);
      double distanciaCentro;
      for (int i = 0; i < pos.length; i++)
      {
        // Ajustar los jugadores en campo propio
        if (pos[i].getY() > 0)
        {
          pos[i] = new Posicion( pos[i].getX(), -1 );
          distanciaCentro = Constantes.centroCampoJuego.distancia(pos[i]);
          if (distanciaCentro < Constantes.DISTANCIA_SAQUE)
          {
            pos[i] = pos[i].moverPosicion( 0, (distanciaCentro - Constantes.DISTANCIA_SAQUE));
          }
        }
      }
      return pos;
    }

  protected Vector<Comando> moverPortero( SituacionPartido sp)
  {
    Vector<Comando> comandos = new Vector<Comando>();
    
    Posicion posicion;

double LIMITE_DEL_POSTE = 2;  // Distancia l�mite a la que bascular� m�s all� del poste
  
      // Tactica Test. El portero bascula 1/4 de la pelota (30m => 7.5m)
      double posicionX = sp.balon().getX();
      if (posicionX > (Constantes.posteDerArcoInf.getX() + LIMITE_DEL_POSTE))
      {
        posicionX = Constantes.posteDerArcoInf.getX() + LIMITE_DEL_POSTE;
      }
      else if (posicionX < (Constantes.posteIzqArcoInf.getX() - LIMITE_DEL_POSTE))
      {
        posicionX = Constantes.posteIzqArcoInf.getX() - LIMITE_DEL_POSTE;
      }
      
      posicion = new Posicion( posicionX, y_portero);
  
      comandos.add(new ComandoIrA(0, posicion));
      comandos.add(new ComandoIrA(1, posicion.moverPosicion( 2.5, 1)));
      comandos.add(new ComandoIrA(2, posicion.moverPosicion(- 2.5, 1)));

    return comandos;
  }
  protected Vector<Comando> moverDefensa( SituacionPartido sp)
  {
    Vector<Comando> comandos = new Vector<Comando>();
    
    Posicion balon = sp.balon();
    if (balon.getY() > y_medios)
    {
      Posicion[] posicionesIniciales = this.getPosicionInicial(sp);
      
      int[] defensas = new int[] {3, 4};
      int[] indicesRivalCercano;
      int[] rivalesMarcados = new int[11];
      for (int i = 0; i < 11; i++)
        rivalesMarcados[i] = 0; // portero
     Posicion destino;
     double angulo;
     for (int i = 0; i < defensas.length; i++)
      {
        indicesRivalCercano = posicionesIniciales[defensas[i]].indicesMasCercanos(sp.rivales(), rivalesMarcados);
        for (int j = 0; j < rivalesMarcados.length; j++)
        {
          if (sp.rivales()[indicesRivalCercano[j]].distancia( posicionesIniciales[defensas[i]] ) <= 15)
          {
            rivalesMarcados[indicesRivalCercano[j]] = indicesRivalCercano[j];
            destino = sp.rivales()[indicesRivalCercano[j]];
            angulo = destino.angulo(sp.balon());
            destino = destino.moverAngulo(angulo, 5);
            comandos.add( new ComandoIrA(defensas[i], destino));
            break;
          }
        }
      }
    }
    return comandos;
  }
  protected Vector<Comando> moverMedia( SituacionPartido sp)
  {
    Vector<Comando> comandos = new Vector<Comando>();
    
double LIMITE_DE_ALEJAMIENTO = 10;  // Distancia l�mite a la que bascular� m�s all� de la posicion inicial

boolean bascularMedios = true;

    Posicion[] posicionesIniciales = this.getPosicionInicial(sp);

    // Adelantar posicion cuando se ataca
    if (sp.balon().getY() > 15)
    {
      comandos.add( new ComandoIrA(6, posicionesIniciales[6].moverPosicion(0, 15) ));
      comandos.add( new ComandoIrA(7, posicionesIniciales[7].moverPosicion(0, 15) ));
    }
    // Retrasar posicion cuando se defiende
    if (sp.balon().getY() < y_medioCentro)
    {
      comandos.add( new ComandoIrA(6, posicionesIniciales[6].moverPosicion(0, -15) ));
      comandos.add( new ComandoIrA(7, posicionesIniciales[7].moverPosicion(0, -15) ));
    }

    return comandos;
  }
  protected Vector<Comando> moverAtacantes( SituacionPartido sp)
  {
    Vector<Comando> comandos = new Vector<Comando>();
    
    Posicion posicion;

double LIMITE_DEL_POSTE = 2;  // Distancia l�mite a la que bascular� m�s all� del poste
  
      // Tactica Test. El portero bascula 1/4 de la pelota (30m => 7.5m)
      double posicionX = sp.balon().getX();
      if (posicionX > (Constantes.posteDerArcoInf.getX() + LIMITE_DEL_POSTE))
      {
        posicionX = Constantes.posteDerArcoInf.getX() + LIMITE_DEL_POSTE;
      }
      else if (posicionX < (Constantes.posteIzqArcoInf.getX() - LIMITE_DEL_POSTE))
      {
        posicionX = Constantes.posteIzqArcoInf.getX() - LIMITE_DEL_POSTE;
      }
      
      posicion = new Posicion( posicionX, y_delanteros);
  
      comandos.add(new ComandoIrA(10, posicion));
      comandos.add(new ComandoIrA(9, posicion.moverPosicion(1, 0)));
      comandos.add(new ComandoIrA(8, posicion.moverPosicion(-1, 0)));

    return comandos;
  }
  protected Vector<Comando> seguirPelota( SituacionPartido sp)
  {
    Vector<Comando> comandos = new Vector<Comando>();
    
    Posicion balon = sp.balon();
    int[] indJugadoresExcluir = new int[] { 0,1,2,5,8,9,10 };
    int[] indJugadoresOrdenados =  balon.indicesMasCercanos(sp.misJugadores(), indJugadoresExcluir);
    
    comandos.add( new ComandoIrA(5, balon));
    
    int[] indJugadores = new int[] { 3, 4, 6, 7};
    Vector indJugadoresVector = new Vector();
    indJugadoresVector.add(new Integer(3));
    indJugadoresVector.add(new Integer(4));
    indJugadoresVector.add(new Integer(6));
    indJugadoresVector.add(new Integer(7));
          
Posicion[] posicionesIniciales = getPosicionInicial(sp);
Posicion[] misPosiciones = sp.misJugadores();

    for (int i = 0; i < indJugadoresOrdenados.length; i++)
    {      
      if (indJugadoresVector.contains(new Integer(indJugadoresOrdenados[i])))
      {
        if (balon.distancia(posicionesIniciales[indJugadoresOrdenados[i]]) < 30)
        {
          if (comandos.size() < 4) // solo 1+3
          {
            comandos.add(  new ComandoIrA(indJugadoresOrdenados[i], balon) );
          }
        }
      }
    }
    if (balon.distancia(posicionesIniciales[0]) < 5)
    {
      comandos.add(  new ComandoIrA(0, balon) );
      comandos.add(  new ComandoIrA(1, balon.moverPosicion(2.5, 0)) );
      comandos.add(  new ComandoIrA(2, balon.moverPosicion(-2.5, 0)) );
    }
    int indPrimerDelantero = 8;
    Posicion[] posicionesIni = new Posicion[] { posicionesIniciales[8], posicionesIniciales[9], posicionesIniciales[10] };
    Posicion[] posiciones = new Posicion[] { misPosiciones[8], misPosiciones[9], misPosiciones[10] };
    int indJugador =  balon.indiceMasCercano(posiciones);
    if (balon.distancia(posicionesIni[indJugador]) < 30)
      comandos.add(  new ComandoIrA(indJugador + indPrimerDelantero, balon) );
    
    return comandos;
  }
  protected Vector<Comando> pasarPelota( SituacionPartido sp)
  {
    Vector<Comando> comandos = new Vector<Comando>();
    
      Posicion posDestino, posCamino;
      Vector rematadoresVector = new Vector();
      int[] rematadores = sp.puedenRematar();
      for (int i = 0; i < rematadores.length; i++)
        rematadoresVector.add(new Integer(rematadores[i]));
      Posicion[] mios = sp.misJugadores();
      Posicion[] rivales = sp.rivales();
      boolean regatear = true;
      for(int i = 3; i < 8; i++) 
      {
        posDestino = mios[i].moverPosicion(0, 6);
        posCamino = mios[i].moverPosicion(0, 3);
        if (mios[i].getY() < 25)
        {
          if (rematadoresVector.contains(new Integer(i)))
          {
            regatear = true;
            for (int j = 0; j < rivales.length; j++)
            {
              if (rivales[j].distancia(posDestino) < 6)
              {
                regatear = false;
                break;
              }
              if (rivales[j].distancia( posCamino ) < 12)
              {
                regatear = false;
                break;
              }
            }
            if (regatear)
            {
  //System.out.println("EstamosMuLocos.regatear() = "+i+" desde "+mios[i]+" hacia "+posDestino);
              comandos.add(new ComandoGolpearBalon(i));
              comandos.add(new ComandoIrA(i, posDestino));
            }
          }
        }
//System.err.println(i + ".- " + alineacion[i]);          
      }
      
    return comandos;
  }
  protected Vector<Comando> moverParaSaque( SituacionPartido sp)
  {
    Vector<Comando> comandos = new Vector<Comando>();
    
    if (sp.sacaRival())
    {
      Posicion balon = sp.balon();
      if (balon.distancia(Constantes.centroArcoSup) < 10)
      {
        comandos.add(  new ComandoIrA(8, balon.moverPosicion(0, -5)) );
        comandos.add(  new ComandoIrA(9, balon.moverPosicion(2.5, -5)) );
        comandos.add(  new ComandoIrA(10, balon.moverPosicion(-2.5, -5)) );
      }
    }
    
    return comandos;
  }
  protected Vector<Comando> chutarPelota( SituacionPartido sp)
  {
    Vector<Comando> comandos = new Vector<Comando>();
    
      Posicion posDestino;
      Vector rematadoresVector = new Vector();
      int[] rematadores = sp.puedenRematar();
      for (int i = 0; i < rematadores.length; i++)
        rematadoresVector.add(new Integer(rematadores[i]));
      for(int i = 0; i < 11; i++) 
      {
//        posDestino = mios[i].moverPosicion(0, 20);
        if (rematadoresVector.contains(new Integer(i)))
          comandos.add(new ComandoGolpearBalon(i, Constantes.centroArcoSup, 1.0, 20.0));
//System.err.println(i + ".- " + alineacion[i]);          
      }
      
    return comandos;
  }
  
    public List ejecutar(SituacionPartido sp) 
    {

      LinkedList comandos = new LinkedList();
      
      Posicion[] mios = sp.misJugadores();

      Posicion[] rivales = sp.rivales();

      Posicion[] pos = getPosicionInicial(sp);
      for(int i = 0; i < 11; i++) 
      {
        comandos.add(new ComandoIrA(i, pos[i]));
//System.err.println(i + ".- " + alineacion[i]);          
      }
      
      comandos.addAll( moverPortero(sp));
      comandos.addAll( moverDefensa(sp));
      comandos.addAll( moverMedia(sp));
      comandos.addAll( moverAtacantes(sp));
      
      comandos.addAll( seguirPelota(sp));
      
      comandos.addAll( pasarPelota(sp));
      
      comandos.addAll( chutarPelota(sp));
      
      comandos.addAll( moverParaSaque(sp));
      

//System.out.println("EstamosMuLocos.ejecutar() = " + sp.iteracion() + " : \n"+TacticaTermineitor.toStringRecursive(comandos) );
      
      return comandos;
    }
    
}